package com.azxc.rapid.auth.sso;

import com.azxc.rapid.auth.constant.AuthConstant;
import com.azxc.rapid.auth.jianguan.SuperviseAuthenticationToken;
import com.azxc.rapid.auth.service.RapidUserDetails;
import com.azxc.rapid.core.tool.api.R;
import com.azxc.rapid.core.tool.support.Kv;
import com.azxc.rapid.core.tool.utils.Func;
import com.azxc.rapid.supervise.feign.ISuperviseClient;
import com.azxc.rapid.system.user.entity.User;
import com.azxc.rapid.system.user.entity.UserInfo;
import com.azxc.rapid.system.user.enums.UserEnum;
import com.azxc.rapid.system.user.feign.IUserClient;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;

import java.util.Map;

/**
 * @author zlt
 * <p>
 * Blog: https://zlt2000.gitee.io
 * Github: https://github.com/zlt2000
 */
@Slf4j
@Setter
@Getter
public class SsoAuthenticationProvider /*implements AuthenticationProvider*/ {



	//@Autowired
	private IUserClient userClient;

	public SsoAuthenticationProvider(IUserClient userClient){
		this.userClient=userClient;
	}

    //@Override
    public Authentication authenticate(Authentication authentication) {
		if (!supports(authentication.getClass())) {
			return null;
		}
		SsoAuthenticationToken token = (SsoAuthenticationToken) authentication;
		// 从数据库查询 数据
		Map paramMap= (Map) token.getDetails();
		String tenantiId=paramMap.get("tenantId").toString();
		String uid=paramMap.get("uid").toString();
		RapidUserDetails rapidUserDetails;

		R<User>userR= userClient.userInfoById(Long.valueOf(uid));
		if(!userR.isSuccess()||null==userR.getData()||userR.getData().getAccount()==null){
			throw new InvalidGrantException("无该用户");
		}
		R<UserInfo> result2= userClient.userInfo(tenantiId, userR.getData().getAccount(), UserEnum.WEB.getName());


		//R<UserInfo> result2= superviseClient.userInfo(token.getPrincipal().toString());
		if (result2.isSuccess()) {
			User user = result2.getData().getUser();
			Kv detail = result2.getData().getDetail();
			if (user == null) {
				throw new InvalidGrantException("sso grant failure, user is null");
			}
			rapidUserDetails = new RapidUserDetails(user.getId(),
				tenantiId, result2.getData().getOauthId(), user.getName(), user.getRealName(), user.getDeptId(), user.getPostId(), user.getRoleId(), Func.join(result2.getData().getRoles()),null,
				user.getName(), AuthConstant.ENCRYPT + user.getPassword(), detail, true, true, true, true,
				AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result2.getData().getRoles())));
		} else {
			throw new InvalidGrantException("supervise grant failure, feign client return error");
		}


		if (rapidUserDetails == null) {
			throw new InternalAuthenticationServiceException("无法获取用户信息");
		}


		SsoAuthenticationToken result =
			new SsoAuthenticationToken(rapidUserDetails, AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result2.getData().getRoles())));
		/**
		 Details 中包含了 ip地址、 sessionId 等等属性
		 其实还可以存储一些我们想要存储的数据，之后我们再利用。、*/

		result.setDetails(token.getDetails());
		return result;
		//return null;
    }

    //@Override
    public boolean supports(Class<?> authentication) {
        return SsoAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
